#include <cstdio>
#include <cstring>

template<typename T>
class RefCountPtr {
public:
	RefCountPtr(T *p) {
		m_ptr = p;
		m_count = new int(0);
		++(*m_count);
	}

	~RefCountPtr() {
		if (NULL != m_ptr) {
			--(*m_count);
		}
		if (*m_count == 0) {
			delete m_ptr;
			delete m_count;
		}
	}

	RefCountPtr& operator=(const RefCountPtr& other) {
		if (NULL != m_ptr) {
			--(*m_count);
		}

		if (m_ptr == other.m_ptr) {
			return *this;
		}
		if (*m_count == 0) {
			delete m_ptr;
			delete m_count;
		}

		m_ptr = other.m_ptr;
		m_count = other.m_count;
		++(*m_count);
		return *this;
	}

	T operator*() {
		return *m_ptr;
	}

	T* operator->() {
		return m_ptr;
	}

private:
	T* m_ptr;
	int* m_count;
};

class A {
public:
	int m_value;
	A(int value) : m_value(value) {}

	~A() {
		printf("destructor\n");
	}
};

int main() {
	RefCountPtr<A> p1 = new A(1);
	RefCountPtr<A> p2 = new A(2);

	p1 = p2;
	printf("%d\n", p1->m_value);

	return 0;
}
